﻿using System;
using System.Text;
using System.Drawing;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static partial class glDRIVE
{
    /*
    函数 gl.gmiv
    线性最小二乘问题的广义逆法
    参数 a: a[m][n]超定方程组的系数矩阵A，返回时其对角线依次给出奇异值，其余元素为0。
    参数 m: 方程个数，也是系数矩阵行数。
    参数 n: 未知数个数，也是系数矩阵的列数。要求 m>=n 。
    参数 b: b[m]存放方程组右端的常数向量。
    参数 x: x[n]返回时方程组的最小二乘解。
    参数 aa: aa[n][m]返回系数矩阵A的广义逆A+。
    参数 eps: 奇异值分解中的控制精度要求。
    参数 u: u[m][m]返回A的奇异值分解式中的左奇异向量U。
    参数 v: v[n][n]返回A的奇异值分解式中的右奇异向量V+。
    参数 ka: ka = max(m,n) + 1。
    参数 inter: 最多迭代次数
    返回值 若<0则表示失败；若>0则表示正常。
    */

    public static string drive_gmiv()
    {
        int i, j, m, n, ka;
        double[] x = new double[3];
        double[,] aa = new double[3, 4];
        double[,] u = new double[4, 4];
        double[,] v = new double[3, 3];
        double[,] a = new double[4, 3]{
            {1.0,1.0,-1.0},
            {2.0,1.0,0.0},
            {1.0,-1.0,0.0},
            {-1.0,2.0,1.0}
        };
        double[] b = new double[4] {
            2.0, -3.0, 1.0, 4.0
        };
        double eps;
        m = 4;
        n = 3;
        ka = 5;
        eps = 0.000001;

        string rs = "";
        rs += gl.html_table("Mat A:", a);
        rs += gl.html_table("Mat B:", b);

        i = gl.gmiv(a, m, n, b, x, aa, eps, u, v, ka, 100);
        if (i <= 0) return "error: 0";

        rs += gl.html_table("最小二乘解 X:", x);
        rs += gl.html_table("最小二乘解 广义逆 A+:", aa);

        return rs;
    }
}